import * as Cesium from 'cesium'
// import testFrag from '@/glsl/test.frag.glsl'
// import testVertex from '@/glsl/test.vert.glsl'

const testVertex = `
  in vec3 position3DHigh;
  in vec3 position3DLow;
  in float batchId;
  in vec4 color;
  in vec3 position;
  out vec4 v_color;

  void main() {
    // vec4 pos = czm_computePosition();   // 返回当前这个顶点的位置
    v_color = color;
    gl_Position = czm_projection * czm_modelView * vec4(position, 1.0);
  }
`

const testFrag = `
  in vec4 v_color;
  uniform float randomNumber;
  out vec4 myFragColor;

  void main() {
    float time = fract(czm_frameNumber / 60.0);
    myFragColor = vec4(1.0, 1.0, 0.0, 1.0);
    // myFragColor = vec4(randomNumber, randomNumber * czm_frameNumber, randomNumber, 1.0);
  }
`
export default class MyPrimitive {
  constructor() {
    this.drawCommand = null
  }
  /**
   * 将经纬度坐标转换为笛卡尔坐标
   * @param {*} i 
   * @param {*} j 
   * @returns [pos.x, pos.y, pos.z]
   */
  transformPos(i, j) {
      const lon1 = 80.25, lat2 = 40.59
      let pos = Cesium.Cartesian3.fromDegrees(lon1 + j * 0.5, lat2 - i * 0.5)
      return [pos.x, pos.y, pos.z]
  }
  /**
   * 根据自定义Geometry生成Primitive对象
   * @returns {Cesium.Primitive}
   */
  generateGeometry() {
    const nx = 100, ny = 100
    const lon1 = 80.25, lat1 = 30.59, lon2 = 114.25, lat2 = 40.59
    /**
     * 这里positions数组存放的是笛卡尔坐标系中的顶点坐标，
     * colors数组存放的是顶点颜色，
     * indices数组存放的是三角面片的顶点索引，
     * 其中positions / 3和colors / 4必须相等。
     */
    const positions = [], colors = [], indices = []
    // i是列索引，j是行索引
    for(let i = 0; i < ny; i++) {
      for(let j = 0; j < nx; j++) {
        let index = i * nx + j
        let nextIndex = (i + 1) * nx + j
        positions.push(...this.transformPos(i, j))
        const color = Cesium.Color.fromRandom({alpha: 1})
        colors.push(color.red, color.green, color.blue, color.alpha)
        if(j < nx - 1 && i < ny - 1) {
          indices.push(index, index + 1, nextIndex, index + 1, nextIndex, nextIndex + 1)
        }
      }
    }
  
    const geometry = new Cesium.Geometry({
      attributes: {
        position: new Cesium.GeometryAttribute({
          /**
           * DOUBLE表示64位双精度浮点数，FLOAT表示32位单精度浮点数。
           * DOUBLE通常用于需要高精度的顶点坐标数据，如位置（position）属性。
           * 使用Cesium.ComponentDatatype.DOUBLE时，顶点数据的值必须传递为Float64Array类型。
           * 而使用Cesium.ComponentDatatype.FLOAT时，则必须传递为Float32Array类型。
           */
          componentDatatype: Cesium.ComponentDatatype.DOUBLE,
          componentsPerAttribute: 3,
          values: new Float64Array(positions)
        }),
        color: new Cesium.GeometryAttribute({
          componentDatatype: Cesium.ComponentDatatype.FLOAT,
          componentsPerAttribute: 4,
          values: new Float32Array(colors)
        })
      },
      primitiveType: Cesium.PrimitiveType.TRIANGLES,
      indices: indices,
      boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
    })
    /**
     * 创建将属性名称映射到唯一位置（索引）的对象 用于匹配顶点属性和着色器程序。
     * { position: 0, color: 1 }
     */
    console.log(Cesium.GeometryPipeline.createAttributeLocations(geometry))
    return geometry
    // this.viewer.scene.primitives.add(new Cesium.Primitive({
    //   geometryInstances: new Cesium.GeometryInstance({
    //     geometry: geometry,
    //   }),
    //   appearance: new Cesium.PerInstanceColorAppearance({
    //     flat: true,   // 使用平面着色，不考虑光照
    //     translucent: false,   // 半透明
    //     vertexShaderSource: testVertex,
    //     fragmentShaderSource: testFrag
    //   }),
    //   // Cesium中的Primitive对象默认使用Web Worker异步加载，可以取消异步加载
    //   asynchronous: false,
    // }))
  }
  createDrawCommand(context) {
    let geometry = this.generateGeometry()
    let vertexArray = Cesium.VertexArray.fromGeometry({
      context: context,
      geometry: geometry,
      attributeLocations: Cesium.GeometryPipeline.createAttributeLocations(geometry)
    })
    let shaderProgram = Cesium.ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: testVertex,
      fragmentShaderSource: testFrag,
      attributeLocations: Cesium.GeometryPipeline.createAttributeLocations(geometry)
    })
    let uniformMap = {
      randomNumber() {
        return Math.random()
      }
    }
    let renderState = Cesium.RenderState.fromCache({
      depthTest: {
        enabled: true,
      },
      depthMask: false,
      blending: Cesium.BlendingState.ALPHA_BLEND,
    })
    this.drawCommand = new Cesium.DrawCommand({
      vertexArray: vertexArray,
      shaderProgram: shaderProgram,
      renderState: renderState,
      uniformMap: uniformMap,
      pass: Cesium.Pass.OPAQUE,
      castShadows: false,
      receiveShadows: false,
      primitiveType: Cesium.PrimitiveType.LINES,
    })
  }
  update(framestate) {
    if(this.drawCommand === null) {
      this.createDrawCommand(framestate.context)
      console.log(framestate.context)
      console.log(framestate.commandList)   // 6个command，分别是clear，depth，stencil，pick，model，scene
    }
    framestate.commandList.push(this.drawCommand)
  }
}
